from datetime import datetime
import os
import socket
import tkinter as tk
import threading

# 创建主窗口
root = tk.Tk()

root.title("HotTransfer Server")

# 始终置顶
# root.wm_attributes("-topmost", True)

# 禁止调整窗口大小 (宽度不可变, 高度不可变)
root.resizable(width=False, height=False)


def receive_file(server_ip, server_port, save_dir):
    global server_socket  # 便于关闭窗口时结束通信

    try:
        # 使用 with 语句管理服务器套接字
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
            server_socket.bind((server_ip, server_port))
            server_socket.listen(1)
            print(f"服务器启动，监听 {server_ip}:{server_port}")

            while True:
                try:
                    # 使用 with 语句管理客户端套接字
                    with server_socket.accept()[0] as client_socket:
                        tips_label.config(fg="#fd6e43", text="接收文件中...")

                        # 接收文件名
                        raw_file_name = (
                            client_socket.recv(1024).split(b"\n")[0].decode()
                        )

                        # 生成保存的文件路径
                        base_name, ext = os.path.splitext(raw_file_name)
                        timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
                        new_file_name = f"{base_name}_{timestamp}{ext}"
                        file_path = os.path.join(save_dir, new_file_name)

                        # 接收文件内容并写入
                        with open(file_path, "wb") as file:
                            while True:
                                data = client_socket.recv(1024)
                                if not data:
                                    break
                                file.write(data)

                        tips_label.config(fg="green", text="文件接收完成")
                        # print(f"文件接收完成，保存为 {file_path}")

                except OSError as e:
                    print(f"客户端通信错误: {e}")
                    tips_label.config(fg="red", text="客户端通信错误，请重新启动服务")
                    start_server_button.config(state=tk.NORMAL)
                    break  # 处理异常时退出当前循环
    except Exception as e:
        print(f"服务器错误: {e}")


def start_server():
    # 禁止再次点击
    start_server_button.config(state=tk.DISABLED)
    # 以新的线程启动
    threading.Thread(
        target=receive_file,
        args=(ip_address_entry.get(), int(port_entry.get()), "."),
        daemon=True,  # 设置为守护线程，随主线程退出
    ).start()
    tips_label.config(fg="green", text="服务已启动")


# IP 地址 标签
ip_address_label = tk.Label(
    root,
    text="IP 地址：",  # 显示的文本
    font=("Kaiti", 14),  # 字体和大小
    fg="darkblue",  # 前景文字颜色
)
ip_address_label.grid(row=0, column=0, padx=(20, 0), pady=(20, 0))

# IP 地址 输入框
ip_address_entry = tk.Entry(root, width=20)
ip_address_entry.grid(row=0, column=1, padx=(0, 20), pady=(20, 0))

# 端口 标签
port_label = tk.Label(
    root,
    text="端口：",
    font=("Kaiti", 14),
    fg="darkblue",
)
port_label.grid(row=1, column=0, padx=(20, 0), pady=(20, 0))

# 端口 输入框
port_entry = tk.Entry(root, width=20)
port_entry.grid(row=1, column=1, padx=(0, 20), pady=(20, 0))

# 启动服务 按钮
start_server_button = tk.Button(root, text="启动服务", command=start_server)
start_server_button.grid(row=2, column=0, padx=(20, 0), pady=(20, 20))

# 提示文字 标签
tips_label = tk.Label(
    root,
    text="服务未启动",
    font=("Kaiti", 12),
    fg="#ea4c89",
)
tips_label.grid(row=2, column=1, pady=(20, 20))

# 更新窗口以计算正确的大小
root.update_idletasks()

# 获取窗口大小
window_width = root.winfo_width()
window_height = root.winfo_height()

# 获取屏幕的宽高
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

# 计算窗口左上角的坐标 (x, y) 以使窗口居中
x = (screen_width // 2) - (window_width // 2)
y = (screen_height // 2) - (window_height // 2)

# 设置窗口的位置，只设置偏移，不改变窗口大小
root.geometry(f"+{x}+{y}")

# 进入主循环
root.mainloop()
